#include "stdint.h"
#include "stdio.h"
#include "string.h"
#include "ringbuff.h"

//#define MAX_PACKAGE_LEN    (sizeof(devStatus_t)+sizeof(attrFlags_t)+10) ///< ���ݻ�������󳤶�  
//#define RB_MAX_LEN          (MAX_PACKAGE_LEN*2)     ///< ���λ�������󳤶�

#define RB_MAX_LEN		20
#define min(a, b) (a)<(b)?(a):(b)                   ///< ȡ��Сֵ

rb_t pRb; 

                                           ///< ���λ������ṹ�����
static uint8_t rbBuf[RB_MAX_LEN];                       ///< ���λ��������ݻ�����

static void rbCreate(rb_t* rb)
{
    if(NULL == rb)
    {
        return;
    }

    rb->rbHead = rb->rbBuff;
    rb->rbTail = rb->rbBuff;
}

//static void rbDelete(rb_t* rb)
//{
//    if(NULL == rb)
//    {
//        return;
//    }

//    rb->rbBuff = NULL;
//    rb->rbHead = NULL;
//    rb->rbTail = NULL;
//    rb->rbCapacity = 0;
//}

static int32_t rbCapacity(rb_t *rb)
{
    if(NULL == rb)
    {

        return -1;
    }

    return rb->rbCapacity;
}

int32_t rbCanRead(rb_t *rb)
{
    if(NULL == rb)
    {
        return -1;
    }

    if (rb->rbHead == rb->rbTail)
    {
        return 0;
    }

    if (rb->rbHead < rb->rbTail)
    {
        return rb->rbTail - rb->rbHead;
    }

    return rbCapacity(rb) - (rb->rbHead - rb->rbTail);
}

static int32_t rbCanWrite(rb_t *rb)
{
    if(NULL == rb)
    {
        return -1;
    }

    return rbCapacity(rb) - rbCanRead(rb);
}

int32_t rbRead(rb_t *rb, void *data, size_t count)
{
    int copySz = 0;

    if(NULL == rb)
    {
        return -1;
    }

    if(NULL == data)
    {
        return -1;
    }

    if (rb->rbHead < rb->rbTail)
    {
        copySz = min(count, rbCanRead(rb));
        memcpy(data, rb->rbHead, copySz);
        rb->rbHead += copySz;
        return copySz;
    }
    else
    {
        if (count < rbCapacity(rb)-(rb->rbHead - rb->rbBuff))
        {
            copySz = count;
            memcpy(data, rb->rbHead, copySz);
            rb->rbHead += copySz;
            return copySz;
        }
        else
        {
            copySz = rbCapacity(rb) - (rb->rbHead - rb->rbBuff);
            memcpy(data, rb->rbHead, copySz);
            rb->rbHead = rb->rbBuff;
            copySz += rbRead(rb, (char*)data+copySz, count-copySz);
            return copySz;
        }
    }
}

int32_t rbWrite(rb_t *rb, const void *data, size_t count)
{
    int tailAvailSz = 0;

    if(NULL == rb)
    {
        return -1;
    }

    if(NULL == data)
    {
        return -1;
    }

    if (count >= rbCanWrite(rb))
    {
        return -1;
    }

    if (rb->rbHead <= rb->rbTail)
    {
        tailAvailSz = rbCapacity(rb) - (rb->rbTail - rb->rbBuff);
        if (count <= tailAvailSz)
        {
            memcpy(rb->rbTail, data, count);   
            rb->rbTail += count;
            if (rb->rbTail == rb->rbBuff+rbCapacity(rb))//���������������������βָ������ָ�򻺳���ͷ��
            {
                rb->rbTail = rb->rbBuff;
            }
            return count;
        }
        else
        {
            memcpy(rb->rbTail, data, tailAvailSz);
            rb->rbTail = rb->rbBuff;

            return tailAvailSz + rbWrite(rb, (char*)data+tailAvailSz, count-tailAvailSz);
        }
    }
    else
    {
        memcpy(rb->rbTail, data, count);
        rb->rbTail += count;
        return count;
    }
}

void ringBuffInit(void)
{    
    pRb.rbCapacity = RB_MAX_LEN;
    pRb.rbBuff = rbBuf;
    rbCreate(&pRb);
}

//void UART_IRQ_FUN(void)
//{
//    uint8_t value = 0;
//    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
//    {
//        USART_ClearITPendingBit(USART2,USART_IT_RXNE);
//        value = USART_ReceiveData(USART2);

//        gizPutData(&value, 1);
//    }
//}
